本文转自

简书 - [阿策神奇] - Flutter 61: 图解基本 Button 按钮小结 (一)

简书 - [阿策神奇] - Flutter 62: 图解基本 Button 按钮小结 (二)

本站个人笔记本使用,还请大家移步关注原作者。

此处只作备份,以防止作者删除。

Button 在日常中是必不可少的,小菜尝试过不同类型的 Button,也根据需求自定义过,今天小菜系统的学习一下最基本的 Button

Flutter 中没有 Button Widget,但提供了很多不同类型的 Child Button Widget;小菜分析源码整体可分为 RawMaterialButtonIconButton 两类;

其中 RaisedButton / FlatButton / OutlineButton 继承自 MaterialButtonMaterialButton 是对 RawMaterialButton 的封装;而BackButton / CloseButton / PopupMenuButton 继承自 IconButton;最终 RawMaterialButtonIconButton 都是由 ConstrainedBox 填充绘制;

lixyz 按:按照原作者的说法,BackButton 等是 IconButton 的子类,但是通过查看源码发现 BackButton 是 BackButton extends StatelessWidget,究竟是怎么 回事儿呢?

原因是这样的,看 BackButton 的源码:

可以看到,build 方法 返回的还是一个 IconButton,与其说是 IconButton 的子类,不如说是装饰者模式的一个应用。

###IconButton 系列

IconButton 系列属于图标按钮,使用相对简单;其核心是 InkResponse 水波纹效果;

IconButton

#####源码分析

分析源码,其中 icononPressed 是必须要设置的,其余属性根据需求而适当调整;

案例尝试
  1. 小菜首先尝试最基本的 IconButton;长按会由 tooltip 提醒,点击为默认主题色;

  2. 小菜尝试其中几个属性;其中 icon 颜色为 cyan,点击高亮背景色为 deepPurple,水波纹颜色为 redAccent;注意当 icon 自身设置颜色时 color 属性不生效;

  3. 小菜尝试不可点击时,icon 颜色为 disabledColor 设置的 green;同样若 icon 本身设置了颜色,disabledColor 不生效;注意:onPressed: nullonPressed: ()=> null 不同,前者代表无点击事件;后者代表有点击事件,只是点击无操作;

  4. iconWidget 采用 Icon / Image / ImageIcon 等均可;

BackButton

BackButton 作用非常明确,一般用作返回上一个页面;

源码分析

分析源码,BackButton 继承自 IconButton,只允许设置图标颜色,图标样式 AndroidiOS 不同且不可修改;点击时会优先判断 maybePop 是否可以返回上一页;

案例尝试

CloseButton

CloseButton 一般用作导航栏关闭按钮与 BackButton 类似;

源码分析

分析源码,CloseButton 继承自 IconButton,无需设置任何属性;点击时会优先判断 maybePop 是否可以返回上一页;

#####案例尝试

 


RawMaterialButton 系列

RawMaterialButton

RawMaterialButtonMaterialButton 的基础,核心是由 MaterialInkWell 等组成;但不可用当前 ThemeButtonTheme 来计算未指定参数的默认值;

源码分析

分析源码可知,RawMaterialButton 没有设置宽高的属性,可根据 padding 或外层依赖 Container 适当调整位置和大小;默认最小尺寸为 88px \* 36px

案例尝试

小菜定义了一个基本的按钮,并监听其高亮改变时状态,与我们常见的按钮基本一致;

FloatingActionButton

FloatingActionButtonRawMaterialButton 的封装,主要用于浮动在屏幕内容之上,一般是位于底部左右角或中间;一般一个页面只有一个;

源码分析
案例尝试
  1. 小菜尝试一个基本的 FloatingActionButton;长按会有 tooltip 提示;

  2. foregroundColor 为按钮上层子元素颜色,若子元素本身设置颜色则不生效;backgroundColor 为按钮背景色;

  3. elevation 按钮默认阴影高度,即 z 轴高度;highlightElevation 为点击高亮时阴影高度;

  4. mini 是否展示成小尺寸模式;materialTapTargetSize 为配置目标的最小点击尺寸,padded 为默认的 48px \* 48pxAndroid 推荐尺寸;shrinkWrap 为缩小到 Material 提供的最小尺寸;

  5. shape 为样式尺寸;clipBehavior 为抗锯齿效果;

  6. heroTag 动画标签,默认的是 FloatingActionButtonAnimator.scaling;且 heroTag 默认是相同的,可以自定义为唯一标签;小菜设置上一页面与当前页面 FloatingActionButtonheroTag 相同;

  7. FloatingActionButton 提供了 .extended 方式创建代表标签样式的,非正方形的按钮样式;其余属性无差;

  8. 针对特殊的个性化,FloatingActionButton 展示的大小可能会有所不同;小菜尝试了几种方式;

    1. 通过最基本的 RawMaterialButton 实现 FloatingActionButton 样式,外层添加 Container 约束大小;小菜比较推荐方式一,灵活性更高;

    2. 借助 FittedBox 将按钮整体放大到 Container 约束范围内;

    3. SizeBoxFittedBox 约束方式不同,只是整体范围变大,其内部按钮按 Material 建议样式展示;

    4. scaleFittedBox 类似,按比例缩放;

MaterialButton

源码分析

分析源码可知,MaterialButton 作为其他 Button 父类,各属性比较清晰明了,有 hight 属性可设置 Button 高度,其子类 Button 只可通过 padding 或其他方式调整高度;

案例尝试

小菜测试发现 hight 可以设置 MaterialButton 高度,但 shape 按钮形状却不适用;其父类 RawMaterialButton 却正常;小菜尝试网上大神的处理方式是外层依赖 Material 并需要 clip 裁切成 shape 样式;有待进一步学习;

RaisedButton / FlatButton

源码分析

分析源码可知,RaisedButtonFlatButton 基本完全相同,只是 RaisedButton 多了一些阴影高度的特有属性,小菜准备同时对两类 Button 进行尝试,比较两者的不同;

案例尝试
  1. 小菜首先尝试最基本的 RaisedButton / FlatButton 可点击和不可点击样式;

  2. ButtonTextTheme 为默认子元素主题,可以设置基本的三种主题样式:nomal 对应 [ThemeData.brightness]primary 对应 [ThemeData.primaryColor]accent 对应 [ThemeData.accentColor];展示效果比较明显;

  3. textColor 为子 Widget 中元素颜色,不仅为文字颜色;disabledTextColor 为不可点击时子 Widget 元素颜色;splashColor 为点击时水波纹颜色;

  4. colorButton 背景色;highlightColor 为点击时高亮背景色;disabledColor 为不可点击时背景色;

  5. shapeButton 形状;因按钮没有 Materialhight 属性,需要采用 padding 或外层依赖其他 Widget 调整按钮大小;

  6. colorBrightness 代表颜色对比度,一般分为 light / dark 两种;一般时深色的背景需要浅色的文字对比,浅色的背景需要深色的文字对比;

  7. RaisedButton / FlatButton 均提供了 .icon 带图标的简单方式,icon / label 两个属性是必须属性;注意,.icon 方式中 RaisedButton 没有 padding 属性;

OutlineButton

源码分析

分析源码可知,OutlineButton 与其他两种按钮略有不同,强调边框的样式属性且无长按的 tooltip 属性;

案例尝试
  1. 小菜首先尝试一个最基本的 OutlineButton;长按无提醒;

  2. 小菜尝试与其他按钮相同的几类按钮属性,使用方式相同;

  3. 以下为 OutlineButton 特有属性:borderSide 代表边框样式;disabledBorderColor 代表不可点击时边框颜色;highlightedBorderColor 代表高亮时边框颜色;其中 borderSide 可以设置边框颜色宽度及样式(solid / none);

  4. OutlineButton 还提供了 .icon 带图标的简单方式,icon / label 两个属性是必须属性;

扩展

1. textColor 的作用?

小菜原来以为按钮的子元素是 Widget,可自由设置各类效果,单独的 textColor 是否会略显多余;可实际并非如此,子元素设置颜色等之后 textColor 不生效;但 textColor 与主题相关;小菜以 OutlineButton 为例,一目了然;

2. 阴影如何改颜色?

使用 RaisedButton 时会自带阴影效果,阴影的高度和高亮时的阴影高度均可自由设置;但是阴影的颜色应该如何处理呢,官方暂未提供阴影效果属性;小菜尝试了网上大神的方式,RaisedButton 外层依赖带模糊阴影效果的 Container;小菜借鉴并稍微调整一下,解决方案并非最佳,仅作尝试;

初始时定义一个默认的高度 height 作为阴影高度,监听按钮的 onHighlightChanged 方法更改 height 高度作为高亮时阴影高度;

建议:

  1. 使用高亮颜色时 highlightElevation 建议设置为 0.0

  2. 若按钮有样式设置,依赖的 Container 也要设置相同的 shape 样式;